﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using SerialPortHelperLib;
using System.IO.Ports;
using System.IO;
using XChip_Common;
using System.Diagnostics;
using System.Threading;

namespace XChipTool
{
    public partial class Xchip_ConsReadWin : DevExpress.XtraEditors.XtraForm
    {
        public SerialPort sPortTemp { get; set; }

        public bool m_open = false;
        public StringBuilder msgSb = new StringBuilder();
        // 定义一个静态变量来保存类的实例
        private static Xchip_ConsReadWin _xchip_ConsReadWin;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        // 定义私有构造函数，使外界不能创建该类实例

        private bool IsUsbOpen = false;
        private Xchip_ConsReadWin(bool isUsbOpen = false)
        {
            IsUsbOpen = isUsbOpen;
            InitializeComponent();
            SerialSend.SendSerialSendClick2 += Sread_SendSensor_i2cClick;
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static Xchip_ConsReadWin GetInstance()
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xchip_ConsReadWin == null || _xchip_ConsReadWin.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xchip_ConsReadWin == null || _xchip_ConsReadWin.IsDisposed)
                    {
                        _xchip_ConsReadWin = new Xchip_ConsReadWin();
                    }
                }
            }
            return _xchip_ConsReadWin;
        }

        private void Sread_SendSensor_i2cClick(string msg)
        {
            setShowMsg(msg);
        }

       

        public void setShowMsg(string msg)
        {
            if (this.IsHandleCreated)
            {
                msgSb.AppendLine(msg);
                this.Invoke((EventHandler)(delegate
                {
                    //if (memoEdit1.Text.Length > 10000)
                    //{
                    //    memoEdit1.Text = "";
                    //}
                    //追加的形式添加到文本框末端，并滚动到最后。     
                this.memoEdit1.Text = string.Format("{0} \r\n {2} {1}", this.memoEdit1.Text, msg, "");
                this.memoEdit1.SelectionStart = memoEdit1.Text.Length;
                this.memoEdit1.ScrollToCaret();

             }));
            }
        }



        public void setShowMsg()
        {
            this.Invoke((EventHandler)(delegate
            {             
                 memoEdit1.Text = "";
                 msgSb = new StringBuilder();
            }));
        }

        private void simpleButton2_Click(object sender, EventArgs e)
        {
            msgSb = new StringBuilder();
            if (portusbBtn.ImageOptions.ImageUri.Uri.Contains("AlignVerticalRight"))
            {
                if (!IsUsbOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("USB未打开");
                    return;
                }
                uint pVule = 0x0;

                for (int i = (int)Convert.ToUInt32(sensor_reg.Text, 16); i < Convert.ToUInt32(sensor_end_add.Text, 16) + 1; i++)
                {
                    bool isbool;
                    if (IntPtr.Size == 8)
                    {
                        isbool = XChipUSB.UsbI2cRead64(Convert.ToUInt32(string.IsNullOrEmpty(sensor_add.Text) ? "0" : sensor_add.Text, 16),
                     Convert.ToUInt32(string.IsNullOrEmpty(sensor_reg.Text) ? "0" : i.ToString("X6"), 16),
                     ref pVule, Mode_comboBoxEdit.SelectedIndex, usbcomboTime.SelectedIndex);
                    }
                    else
                    {
                        isbool = XChipUSB.UsbI2cRead86(Convert.ToUInt32(string.IsNullOrEmpty(sensor_add.Text) ? "0" : sensor_add.Text, 16),
                     Convert.ToUInt32(string.IsNullOrEmpty(sensor_reg.Text) ? "0" : i.ToString("X6"), 16),
                     ref pVule, Mode_comboBoxEdit.SelectedIndex, usbcomboTime.SelectedIndex);
                    }
                    if (isbool)
                    {
                        setShowMsg("0x:" + i.ToString("X6") + " 0x:" + pVule.ToString("X2"));
                    }
                }
                
                return;
            }


            if (!sPortTemp.IsOpen)//串口检测
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口未打开");
                return;
            }

            int step_len=1;

            switch (reg_len.Text)
            {

                case "1": step_len=1;
                    break;
                case "2": step_len = 2;
                    break;
                default:
                    break;
            }

            // var radio = radioGroup1.SelectedIndex;
            string mode= Mode_comboBoxEdit.Text;

            bool ischeck1 = false;
            bool ischeck2 = false;
            bool ischeck3 = false;
            switch (mode)
            {
                case "8Addr8Data": ischeck1 = true; break;
                case "16Addr8Data": ischeck2 = true; break;
                case "16Addr16Data": ischeck3 = true; break;
                default:
                    break;
            }

            try
            {
                Sensor_i2c sread = new Sensor_i2c(Convert.ToUInt32(string.IsNullOrEmpty(sensor_add.Text) ? "0" : sensor_add.Text, 16),
                Convert.ToUInt32(string.IsNullOrEmpty(sensor_reg.Text) ? "0" : sensor_reg.Text, 16),
                0,
                ischeck1, ischeck2, ischeck3,
                sPortTemp);


                sread.SendSensor_i2cClick += Sread_SendSensor_i2cClick;
                uint myEndAdd = Convert.ToUInt32(string.IsNullOrEmpty(sensor_end_add.Text) ? "0" : sensor_end_add.Text, 16);
                uint myRegX = Convert.ToUInt32(string.IsNullOrEmpty(sensor_reg.Text) ? "0" : sensor_reg.Text, 16);

                if (myEndAdd != 0 && myEndAdd > myRegX)
                {
                    //获取写入TXT的字符串
                    sread.ReadRegByLoop(myEndAdd, step_len);
                }
                else
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("输入值有误,请重新输入", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch
            {
                //DevExpress.XtraEditors.XtraMessageBox.Show("输入值有误,请重新输入：");
            }
        }

        private void export_txt_simpleButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(memoEdit1.Text))
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("文本不能为空,请重新输入！");
                return;
            }

            string txt = memoEdit1.Text;
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "TXT文件(*.txt)|*.txt|所有文件|*.*";
            sfd.FileName = string.Format("xchip_register_" + System.DateTime.Now.ToString("yyyy-MM-dd_HH_mm_ss") + ".txt");
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                string SavePath = sfd.FileName;
                if (!txt_en.Checked)
                {
                    using (FileStream stm = File.OpenWrite(SavePath))
                    {
                        txt = txt.Replace(" ", "");
                        if (txt.StartsWith("\r\n"))
                        {
                            txt = txt.Remove(0, 2); // 从索引0开始移除4个字符
                        }
                        byte[] byteArray = System.Text.Encoding.Default.GetBytes(txt);
                        stm.Write(byteArray, 0, byteArray.Length);

                    }
                }
                else
                {
                    string[] lines = txt.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    string result = "";

                    foreach (string line in lines)
                    {
                        if (!string.IsNullOrWhiteSpace(line))
                        {
                            string[] tokens = line.Split(',');
                            if (tokens.Count()< 3)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("数据异常请检查");
                                return;
                            }
                            result += tokens[1].Substring(2);
                        }
                    }

                    result = InsertNewLines(result, 8);
                    using (FileStream stm = File.OpenWrite(SavePath))
                    {

                        byte[] byteArray = System.Text.Encoding.Default.GetBytes(result);
                        stm.Write(byteArray, 0, byteArray.Length);

                    }

                }
                
                DevExpress.XtraEditors.XtraMessageBox.Show("成功");
            }

          
        }
        string InsertNewLines(string str, int interval)
        {
            int count = str.Length / interval;

            for (int i = 1; i <= count; i++)
            {
                str = str.Insert(i * interval + (i - 1), "\n");
            }

            return str;
        }
        private void simpleButton3_Click(object sender, EventArgs e)
        {
            msgSb = new StringBuilder();
            Stopwatch stopwatch = Stopwatch.StartNew(); // 开始计时  
            if (portusbBtn.ImageOptions.ImageUri.Uri.Contains("AlignVerticalRight"))
            {
                if (!IsUsbOpen)
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("USB未打开");
                    return;
                }
                uint pVule = 0x0;
                for (int i = (int)Convert.ToUInt32(textEdit1.Text, 16); i < Convert.ToUInt32(ISP_end_add_TextBox.Text, 16) + 1; i++)
                {
                    byte[] bTemp = new byte[4];
                    var tempUint = getUintToString(i.ToString("X6"));
                    bTemp[0] = (byte)(tempUint & 0xff);
                    bTemp[1] = (byte)(tempUint >> 8 & 0xff);
                    string output = bTemp[1].ToString("X2") + bTemp[0].ToString("X2");
                    bool isbool;
                    if (IntPtr.Size == 8)
                    {
                        isbool = XChipUSB.UsbRegisterRead64(Convert.ToUInt32(textEdit2.Text + output, 16), ref pVule, false);
                    }
                    else
                    {
                        isbool = XChipUSB.UsbRegisterRead86(Convert.ToUInt32(textEdit2.Text + output, 16), ref pVule, false);
                    }
                    if (isbool)
                    {
                        setShowMsg("0x"+ textEdit2.Text + output + ",0x" + pVule.ToString("X2") + ",");
                    }
                }
                // 停止计时  
                //stopwatch.Stop();
                //DevExpress.XtraEditors.XtraMessageBox.Show($"Execution time: {stopwatch.ElapsedMilliseconds} ms {stopwatch.Elapsed.TotalSeconds} 秒");
                return;
            }

            if (!sPortTemp.IsOpen && !m_open)//串口检测
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口未打开");
                return;

            }

            if (textEdit2.Text.Length!=4|| ISP_end_add_TextBox.Text.Length != 4 || textEdit1.Text.Length != 4)
            {

                DevExpress.XtraEditors.XtraMessageBox.Show("长度不为4,请重新输入");
                return;

            }
            if (string.IsNullOrEmpty(textEdit1.Text)||string.IsNullOrEmpty(textEdit2.Text)) { return; }


            int step_len = 1;

            switch (reg_len2.Text)
            {

                case "1":
                    step_len = 1;
                    break;
                case "2":
                    step_len = 2;
                    break;
                default:
                    break;
            }
            try
            {
                uint startAddress = Convert.ToUInt32(textEdit1.Text, 16);
                uint endAddress = Convert.ToUInt32(ISP_end_add_TextBox.Text, 16);

                if (!string.IsNullOrEmpty(ISP_end_add_TextBox.Text) && endAddress > startAddress)
                { 
                    //StringBuilder sb = new StringBuilder();
                  
                    //判读输入文本的长度
                    uint readLength = endAddress - startAddress;
                    uint baseValue = (Convert.ToUInt32(textEdit2.Text, 16) << 16) + startAddress;
                    if (m_open)
                    {
                        for (int i = 0; i <= readLength; i += step_len)
                        {
                            uint readTemp = (uint)(baseValue + i);
                            var pVule =  SerialSend.ReadRegister(readTemp, sPortTemp);
                            setShowMsg("0x:" + readTemp.ToString("X2") + " 0x:" + pVule.ToString("X2"));
                            Thread.Sleep(10);
                        }
                    }
                    else
                    {
                        for (int i = 0; i <= readLength; i += step_len)
                        {
                            uint readTemp = (uint)(baseValue + i);
                            SerialSend.ReadRegister2(0x31, readTemp, sPortTemp);
                        }
                    }
                    
                }

            }
            catch(Exception ex)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show($"输入值有误,请重新输入,异常打印：{ex.ToString()}");
            }
            // 停止计时  
            //stopwatch.Stop();
            //DevExpress.XtraEditors.XtraMessageBox.Show($"Execution time: {stopwatch.ElapsedMilliseconds} ms {stopwatch.Elapsed.TotalSeconds} 秒");
            // 输出执行时间，例如以毫秒为单位  
            //Console.WriteLine($"Execution time: {stopwatch.ElapsedMilliseconds} ms");
        }
        //清理文本框 
        private void clear_button_Click(object sender, EventArgs e)
        {
            setShowMsg();
        }

        //切换页面清空文本框
        private void tabPane1_SelectedPageChanged(object sender, DevExpress.XtraBars.Navigation.SelectedPageChangedEventArgs e)
        {
            setShowMsg();
        }

        private void portusbBtn_Click(object sender, EventArgs e)
        {
            if (portusbBtn.ImageOptions.ImageUri.Uri.Contains("AlignVerticalLeft"))
            {
                portusbBtn.ImageOptions.ImageUri.Uri = "AlignVerticalRight;Size16x16;Office2013";
                //radioGroup1.Properties.Items.Remove(new DevExpress.XtraEditors.Controls.RadioGroupItem() { Description = "" });
                usblabtime.Show();
                usbcomboTime.Show();
            }
            else
            {
                portusbBtn.ImageOptions.ImageUri.Uri = "AlignVerticalLeft;Size16x16;Office2013";
                usblabtime.Hide();
                usbcomboTime.Hide();
            }
        }
        public static Xchip_ConsReadWin GetInstance(bool isUsbOpen)
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xchip_ConsReadWin == null || _xchip_ConsReadWin.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xchip_ConsReadWin == null || _xchip_ConsReadWin.IsDisposed)
                    {
                        _xchip_ConsReadWin = new Xchip_ConsReadWin(isUsbOpen);
                    }
                }
            }
            return _xchip_ConsReadWin;
        }

        private void Xchip_ConsReadWin_Load(object sender, EventArgs e)
        {
            string[] listusbcomb = new string[] { "立即读写", "EOF中断来后读写", "SOF中断来后读写", "其他时间读写" };
            usbcomboTime.Properties.Items.AddRange(listusbcomb);
            usbcomboTime.Text = listusbcomb[0];
            if (IsUsbOpen)
            {
                portusbBtn.ImageOptions.ImageUri.Uri = "AlignVerticalRight;Size16x16;Office2013";
                usblabtime.Show();
                usbcomboTime.Show();
            }
            else
            {
                portusbBtn.ImageOptions.ImageUri.Uri = "AlignVerticalLeft;Size16x16;Office2013";
                usblabtime.Hide();
                usbcomboTime.Hide();
            }
        }
        private static UInt32 getUintToString(string addr)
        {
            if (string.IsNullOrEmpty(addr))
            {
                return 0x0;
            }
            else if (addr.Contains("0x"))
            {
                var temp = addr.Replace("0x", "").Trim();
                return Convert.ToUInt32(temp, 16);
            }
            else
            {

                return Convert.ToUInt32(addr.Trim(), 16);
            }
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            string input = memoEdit1.Text.Trim();
            List<string> resultList = input.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            List<string> filteredList = new List<string>();
            for (int i = 0; i < resultList.Count; i++)
            {
                if (resultList[i].Contains("W:")|| resultList[i].Contains("0x8050004E") 
                    || resultList[i].Contains("0x8050004D") || resultList[i].Contains("0x80250003") 
                    || resultList[i].Contains("0x8025000"))
                {
                    continue;
                }
                filteredList.Add(resultList[i] );
            }
            memoEdit1.Text = string.Join("\r\n", filteredList);
        }
    }
}